package com.xiaoyu.izf.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.xiaoyu.izf.model.CommissionLog;
import com.xiaoyu.izf.model.page.DataTableBean;
import com.xiaoyu.izf.model.page.ParamListBean;
import com.xiaoyu.izf.repository.CommissionLogDao;
import com.xiaoyu.izf.multivalues.TwoValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Map;

@Service
public class CommissionLogService extends BaseService {

    @Autowired
    private CommissionLogDao commissionLogDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public DataTableBean list(ParamListBean param){
        PageRequest pageRequest = buildPageRequestSort(param.getPageNo(), param.getPageLength(), "id",param.getFieldName(),param.getCompositorType());

        //添加查询条件
        Page<CommissionLog> page = commissionLogDao.findAll(new Specification<CommissionLog>() {

            /**
             * 构建查询条件（Predicate断言对象）
             * @param root entity：UserInfo
             * @param query
             * @param cb 条件构建器
             * @return
             */
            @Override
            public Predicate toPredicate(Root<CommissionLog> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                //断言列表，可以添加多个断言
                List<Predicate> predicates = Lists.newArrayList();
                //准备结合断言链
                predicates.add(cb.conjunction());

                if (StringUtils.hasLength(param.getParam().get("currentUserName"))){
                    //使用CriteriaBuilder条件构建器构建断言，并加入断言列表
                    predicates.add(
                            //断言为equals(期待值，实际值)，跟junit的断言类似
                            cb.equal(root.get("currentUser").get("userName").as(String.class),param.getParam().get("currentUserName")));
                }

                if (StringUtils.hasLength(param.getParam().get("uid"))){
                    //使用CriteriaBuilder条件构建器构建断言，并加入断言列表
                    predicates.add(
                            //断言为equals(期待值，实际值)，跟junit的断言类似
                            cb.equal(root.get("uid").as(Integer.class),param.getParam().get("uid")));
                }

                if (StringUtils.hasLength(param.getParam().get("gradeType"))){
                    //使用CriteriaBuilder条件构建器构建断言，并加入断言列表
                    predicates.add(
                            //断言为equals(期待值，实际值)，跟junit的断言类似
                            cb.equal(root.get("gradeType").as(Integer.class),param.getParam().get("gradeType")));
                }

                if (StringUtils.hasLength(param.getParam().get("payStatus"))){
                    //使用CriteriaBuilder条件构建器构建断言，并加入断言列表
                    predicates.add(
                            //断言为equals(期待值，实际值)，跟junit的断言类似
                            cb.equal(root.get("payStatus").as(Integer.class),param.getParam().get("payStatus")));
                }

                if (StringUtils.hasLength(param.getParam().get("sourceUserName"))){
                    //使用CriteriaBuilder条件构建器构建断言，并加入断言列表
                    predicates.add(
                            //断言为equals(期待值，实际值)，跟junit的断言类似
                            cb.equal(root.get("sourceUser").get("userName").as(String.class),param.getParam().get("sourceUserName")));
                }

                if (StringUtils.hasLength(param.getParam().get("sourceNickName"))){
                    //使用CriteriaBuilder条件构建器构建断言，并加入断言列表
                    predicates.add(
                            //断言为equals(期待值，实际值)，跟junit的断言类似
                            cb.equal(root.get("sourceUser").get("nickName").as(String.class),param.getParam().get("sourceNickName")));
                }

                predicates.add(
                        //断言为equals(期待值，实际值)，跟junit的断言类似
                        cb.equal(root.get("logType").as(Integer.class),param.getParam().get("logType")));

                //断言列表加入断言，返回Predicate断言对象，交给jpa执行查询
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        },pageRequest);

//		//无查询条件
//		Page<UserInfo> page = userInfoDao.findAll(pageRequest);

        return dataTableBean(page,param);
    }

    public TwoValue<Double,Double> total(ParamListBean paramListBean){
        Map<String,String> param = paramListBean.getParam();
        String sql = "select sum(cl.total_amount) as totalAmount, sum(cl.commissioin) as totalCommission " +
                "from commission_log cl,user_info ui1,user_info ui2 " +
                "where cl.uid=ui1.id and cl.source_uid=ui2.id";

        if (StrUtil.isNotBlank(param.get("logType"))){
            sql += " and cl.log_type="+param.get("logType");
        }
        if (StrUtil.isNotBlank(param.get("payStatus"))){
            sql += " and cl.pay_status="+param.get("payStatus");
        }
        if (StrUtil.isNotBlank(param.get("uid"))){
            sql += " and cl.uid="+param.get("uid");
        }
        if (StrUtil.isNotBlank(param.get("sourceUserName"))){
            sql += " and ui2.user_name="+param.get("sourceUserName");
        }
        if (StrUtil.isNotBlank(param.get("currentUserName"))){
            sql += " and ui1.user_name="+param.get("currentUserName");
        }
        if (StrUtil.isNotBlank(param.get("sourceNickName"))){
            sql += " and ui2.nick_name="+param.get("sourceNickName");
        }
        if (StrUtil.isNotBlank(param.get("gradeType"))){
            sql += " and cl.grade_type="+param.get("gradeType");
        }
        Map<String,Object> result = jdbcTemplate.queryForMap(sql);

        double totalAmount = 0;
        double totalCommission = 0;
        if (result.get("totalAmount")!=null)
            totalAmount = NumberUtil.div(Convert.toDouble(result.get("totalAmount")),Double.valueOf(100));
        if (result.get("totalCommission")!=null)
            totalCommission = NumberUtil.div(Convert.toDouble(result.get("totalCommission")),Double.valueOf(100));

        return new TwoValue<>(totalAmount,totalCommission);
    }
}
